/**
 * 
 */
package pl.polsl.pum2.pj.rubik;

import pl.polsl.pum2.pj.math.Quaternion3d;

/**
 * Class for managing layer rotation animation.
 */
public class Rotation {

  // cubes to be rotated. usually a layer or a couple of layers.
  private Cube[]            layer;

  // overall animation duration time in milliseconds
  private static final long ANIMATION_DURATION = 400;
  private long              currentDuration;

  // destination rotation quaternion, usually is a fixed 90 degrees rot quat. 
  private Quaternion3d      destRotQuat;

  /**
   * @param layer
   *          an array of cubes to be rotated
   * @param destRotQuat
   *          a destination rotation quaternion to be applied
   */
  public Rotation(Cube[] layer, Quaternion3d destRotQuat) {
    this.layer = layer;
    this.destRotQuat = destRotQuat;
  }

  /**
   * @return true if rotation has ended.
   */
  public boolean update(long dt) {
    currentDuration += dt;
    if (currentDuration >= ANIMATION_DURATION) {
      // apply the destination rotation (90deg)
      for (Cube cube : layer) {
        cube.rotate(destRotQuat);
      }
      return true;
    }

    float progress = (float) currentDuration / ANIMATION_DURATION;
    for (Cube cube : layer) {
      // calculate a spherical interpolation between initial cube quat and the destination quat based on millis passed.
      Quaternion3d slerped = Quaternion3d.slerp(cube.quaternion, Quaternion3d.multiply(cube.quaternion, destRotQuat), progress);
      cube.tempRotation(slerped);
    }
    return false;
  }
}
